
#ifndef W25QXX_H
#define W25QXX_H

#include "dev_prv.h"

#define W25QXX_PAGE_SIZE    (256)

enum 
{
    kW25qxxIns_WritePage = 0x02,
    kW25qxxIns_ReadData = 0x03,
    kW25qxxIns_WriteDisable = 0x04,
    kW25qxxIns_ReadStatus = 0x05,
    kW25qxxIns_WriteEnable = 0x06,
    kW25qxxIns_EraseSector = 0x20,
    kW25qxxIns_ReadJEDECID = 0x9f,
};

typedef struct
{
    uint8_t manufacturer;
    uint8_t memory_type;
    uint8_t capacity;
}w25qxx_id_t;

typedef struct
{
    uint8_t memory;
    uint8_t block;
    uint8_t sector;
}w25qxx_size_t;

typedef union
{
    uint8_t value;
    struct
    {
        uint8_t wip:1;
        uint8_t wel:1;
        uint8_t bp:3;
        uint8_t :2;
        uint8_t srp:1;
    };
}w25qxx_reg_sr_t;

typedef struct
{
    void *bus_handle;
    spi_general_bus_t *bus;
    
    w25qxx_id_t id;
    w25qxx_size_t size;
}w25qxx_t;

extern hal_status_t w25qxx_write(w25qxx_t *ic, uint32_t addr, uint8_t *buff, size_t len);
extern void w25qxx_read(w25qxx_t *ic, uint32_t addr, uint8_t *buff, uint16_t len);
extern hal_status_t w25qxx_erase_sector(w25qxx_t *ic, uint32_t addr);
extern void w25qxx_init(w25qxx_t *ic);

#endif
